﻿using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Urs.Admin.Models.Agents;
using Urs.Admin.Models.Common;
using Urs.Admin.Models.Settings;
using Urs.Admin.Models.Users;
using Urs.Core;
using Urs.Data.Domain.Agents;
using Urs.Data.Domain.Configuration;
using Urs.Data.Domain.Users;
using Urs.Framework.Controllers;
using Urs.Framework.Kendoui;
using Urs.Services.Agents;
using Urs.Services.Configuration;
using Urs.Services.ExportImport;
using Urs.Services.Localization;
using Urs.Services.Logging;
using Urs.Services.Media;
using Urs.Services.Orders;
using Urs.Services.Security;
using Urs.Services.Stores;
using Urs.Services.Users;

namespace Urs.Admin.Controllers
{
    [AdminAuthorize]
    public partial class AgentsController : BaseAdminController
    {
        #region Fields

        private readonly IUserService _userService;
        private readonly IPictureService _pictureService;
        private readonly ILocalizationService _localizationService;
        private readonly IWorkContext _workContext;
        private readonly IActivityLogService _activityLogService;
        private readonly IPermissionService _permissionService;
        private readonly AdminAreaSettings _adminAreaSettings;
        private AgentSettings _agentSettings;
        private readonly ISettingService _settingService;
        private readonly IOrderService _orderService;
        private readonly IAgentService _agentService;
        private readonly IExportManager _exportManager;
        private readonly StoreInformationSettings _storeInformationSettings;

        #endregion

        #region Constructors
        public AgentsController(
            IUserService userService,
            IPictureService pictureService,
            ILocalizationService localizationService,
            IWorkContext workContext,
            IActivityLogService activityLogService,
            IPermissionService permissionService,
            ISettingService settingService,
            AdminAreaSettings adminAreaSettings,
            AgentSettings agentSettings,
            IOrderService orderService,
            IAgentService agentService,
            IExportManager exportManager,
            StoreInformationSettings storeInformationSettings)
        {
            this._userService = userService;
            this._pictureService = pictureService;
            this._localizationService = localizationService;
            this._workContext = workContext;
            this._activityLogService = activityLogService;
            this._permissionService = permissionService;
            this._settingService = settingService;
            this._adminAreaSettings = adminAreaSettings;
            this._agentSettings = agentSettings;
            this._orderService = orderService;
            this._agentService = agentService;
            this._exportManager = exportManager;
            this._storeInformationSettings = storeInformationSettings;
        }

        #endregion

        [NonAction]
        protected string GetCustomerRolesNames(IList<UserRole> customerRoles, string separator = ",")
        {
            var sb = new StringBuilder();
            for (int i = 0; i < customerRoles.Count; i++)
            {
                sb.Append(customerRoles[i].Name);
                if (i != customerRoles.Count - 1)
                {
                    sb.Append(separator);
                    sb.Append(" ");
                }
            }
            return sb.ToString();
        }

        [NonAction]
        protected UserModel PrepareCustomerModelForList(User user, bool prepareAvatar)
        {
            var model = new UserModel()
            {
                Id = user.Id,
                Email = user.Email,
                PhoneNumber = user.PhoneNumber,
                Nickname = user.GetFullName(),
                SystemRoleNames = GetCustomerRolesNames(user.UserRoles.ToList()),
                LastIpAddress = user.LastIpAddress,
                Active = user.Active,
                Approved = user.Approved,
                CreateTime = user.CreateTime,
                LastActivityDate = user.LastActivityTime,
                AdminComment = user.AdminComment,
                AffiliateId = user.AffiliateId,
                ChildNumber = _userService.GetInvitedCount(user.Id)
            };
            if (user.AffiliateId.HasValue)
                model.AffilateName = _userService.GetUserById(user.AffiliateId.Value)?.Nickname;

            if (prepareAvatar)
            {
                model.AvatarPictureUrl = _pictureService.GetPictureUrl(user.AvatarPictureId, 100);
            }
            return model;
        }

        #region List

        public IActionResult List()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageAgents))
                return HttpUnauthorized();

            var model = new AgentListModel();

            return View(model);
        }

        [HttpPost]
        public IActionResult List(PageRequest command, AgentListModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageAgents))
                return HttpUnauthorized();

            var searchCustomerRoleIds = new int[1] { _userService.GetUserRoleBySystemName(SystemRoleNames.Agents).Id };
            var customers = _userService.GetAllUsers(userRoleIds: searchCustomerRoleIds, nickname: model.SearchNickname,
               phone: model.SearchPhone,
              pageIndex: command.Page - 1, pageSize: command.Limit);
            var gridModel = new ResponseResult
            {
                data = customers.Select(x => PrepareCustomerModelForList(x, true)),
                count = customers.TotalCount
            };
            return Json(gridModel);
        }

        [HttpPost]
        public IActionResult Active(CheckboxModel checkbox)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageAgents))
                return HttpUnauthorized();

            var customer = _userService.GetUserById(checkbox.Id);
            if (customer == null)
                return Json(new { error = 1 });

            if (checkbox.Checked)
                customer.Approved = true;
            else
                customer.Approved = false;
            _userService.UpdateUser(customer);

            return Json(new { success = 1 });
        }

        public IActionResult AgentUser()
        {
            return View();
        }
        /// <summary>
        /// 分销用户设置 
        /// </summary>
        /// <param name="page">页码（默认：1）</param>
        /// <param name="size">页大小（默认值：12）</param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AgentUser(PageRequest command)
        {
            var list = _agentService.GetUserList(command.Page - 1, command.Limit);

            var userlist = new List<AgentUsersModel>();
            foreach (var item in list)
            {
                var agent = _userService.GetUserById(item.UserId);
                if (agent == null) continue;
                var userModel = new AgentUsersModel()
                {
                    Id = item.Id,
                    UserId = item.UserId,
                    Nickname = agent?.GetFullName(),
                    Phone = agent.PhoneNumber,
                    CreateTime = item.CreateTime,
                    Rate = item.Rate,
                    ParentRate = item.ParentRate
                };
                userlist.Add(userModel);
            }
            var gridModel = new ResponseResult
            {
                data = userlist,
                count = list.TotalCount
            };
            return Json(gridModel);
        }

        public IActionResult AgentUserEdit()
        {
            var userModel = new AgentUsersModel();
            return View(userModel);
        }

        [HttpPost]
        public IActionResult UserUpdate(AgentUsersModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageAgents))
                return HttpUnauthorized();
            var entity = _agentService.GetAgentUserByUserId(model.UserId);

            if (entity != null)
            {
                entity.Rate = model.Rate;
                entity.ParentRate = model.ParentRate;
                _agentService.UpdateAgentUser(entity);
            }
            else
            {
                entity = new AgentUser()
                {
                    UserId = model.UserId,
                    Rate = model.Rate,
                    ParentRate = model.ParentRate,
                    CreateTime = DateTime.Now
                };
                _agentService.InsertAgentUser(entity);
            }

            return Json(new { success = 1 });
        }

        public IActionResult AgentSet()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            var model = new AgentSettingsModel();
            model.Rate = _agentSettings.Rate;
            model.ParentAgentEnabled = _agentSettings.ParentAgentEnabled;
            model.ParentRate = _agentSettings.ParentRate;
            model.BonusForHandout_Awarded = _agentSettings.BonusForHandout_Awarded;
            model.BonusForHandout_Canceled = _agentSettings.BonusForHandout_Canceled;
            model.Method = _agentSettings.Method;

            return View(model);
        }
        [HttpPost]
        public IActionResult AgentSet(AgentSettingsModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageSettings))
                return HttpUnauthorized();

            if (model.ParentRate >= 100 || model.Rate >= 100)
                return Json(new { error = 1, msg = "佣金比例不能大于100%" });

            if (model.ParentRate < 0 || model.Rate < 0)
                return Json(new { error = 1, msg = "佣金比例不能为负数" });

            if (!model.ParentAgentEnabled)
                model.ParentRate = 0;

            _agentSettings.Method = model.Method;
            _agentSettings.Rate = model.Rate;
            _agentSettings.ParentAgentEnabled = model.ParentAgentEnabled;
            _agentSettings.ParentRate = model.ParentRate;
            _agentSettings.BonusForHandout_Awarded = model.BonusForHandout_Awarded;
            _agentSettings.BonusForHandout_Canceled = model.BonusForHandout_Canceled;
            _settingService.SaveSetting(_agentSettings);

            //activity log
            _activityLogService.InsertActivity("EditSettings", _localizationService.GetResource("ActivityLog.EditSettings"));

            return Json(new { success = 1 });
        }
        public IActionResult Users(int Id)
        {
            ViewBag.Id = Id;
            return View();
        }
        /// <summary>
        /// 我的分销用户 
        /// </summary>
        /// <param name="page">页码（默认：1）</param>
        /// <param name="size">页大小（默认值：12）</param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Users(PageRequest command, int Id)
        {
            var invitees = _userService.GetInvitations(Id, command.Page - 1, command.Limit);
            var gridModel = new ResponseResult
            {
                data = invitees.Select(item =>
                {
                    return new AgentUsersModel()
                    {
                        Id = item.Id,
                        Nickname = item?.GetFullName(),
                        Phone = item.PhoneNumber,
                        CreateTime = item.CreateTime
                    };
                }),
                count = invitees.TotalCount
            };
            return Json(gridModel);

        }
        public IActionResult Orders(int Id)
        {
            ViewBag.Id = Id;
            return View();
        }
        /// <summary>
        /// 我的分销订单
        /// </summary>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Orders(PageRequest command, int Id)
        {

            var orders = _orderService.GetOrdersByAffiliateId(Id, pageIndex: command.Page - 1, pageSize: command.Limit);

            var gridModel = new ResponseResult
            {
                data = orders.Select(item =>
                {
                    var user = _userService.GetUserById(item.UserId);
                    return new AgentOrdersModel()
                    {
                        UserId = user.Id,
                        Nickname = user?.GetFullName(),
                        OrderId = item.Id,
                        OrderCode = item.Code,
                        OrderStatusId = item.OrderStatusId,
                        OrderStatus = item.OrderStatus.GetLocalizedEnum(_localizationService),
                        OrderTotal = PriceFormatter.FormatPrice(item.OrderTotal),
                        Remark = item.Remark,
                        CreatedTime = item.CreateTime
                    };
                }),
                count = orders.TotalCount
            };
            return Json(gridModel);
        }

        public IActionResult BonusItems(int Id)
        {
            ViewBag.Id = Id;
            return View();
        }
        /// <summary>
        /// 我的分红明细
        /// </summary>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult BonusItems(PageRequest command, int Id)
        {
            var orders = _agentService.GetList(Id, Id, pageIndex: command.Page - 1, pageSize: command.Limit);

            var list = new List<AgentBonusModel>();
            foreach (var item in orders)
            {
                var c = _userService.GetUserById(item.UserId);
                if (c == null) continue;
                list.Add(new AgentBonusModel()
                {
                    OrderId = item.Id,
                    UserId = c.Id,
                    Nickname = c.Nickname,
                    OrderTotal = PriceFormatter.FormatPrice(item.Price),
                    Fee = item.AgentId == Id ? PriceFormatter.FormatPrice(item.Price) : PriceFormatter.FormatPrice(item.ParentFee),
                    Remark = item.AgentId == Id ? "一级分红" : "二级分红",
                    Cash = item.Cash
                });
            }

            var gridModel = new ResponseResult
            {
                data = list,
                count = orders.TotalCount
            };
            return Json(gridModel);
        }

        #endregion

        #region 导出数据

        public IActionResult ExportExcelAll(AgentListModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders))
                return HttpUnauthorized();

            try
            {
                var searchCustomerRoleIds = new int[1] { _userService.GetUserRoleBySystemName(SystemRoleNames.Agents).Id };
                var users = _userService.GetAllUsers(userRoleIds: searchCustomerRoleIds, nickname: model.SearchNickname,
                   phone: model.SearchPhone);

                byte[] bytes = null;
                using (var stream = new MemoryStream())
                {
                    _exportManager.ExportAgentsToXlsx(stream, users);
                    bytes = stream.ToArray();
                }
                return File(bytes, "text/xls", "agents.xlsx");
            }
            catch (Exception exc)
            {
                return Content(exc.Message);
            }
        }

        public IActionResult ExportOrderExcelAll(int userId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageAgents))
                return HttpUnauthorized();

            try
            {
                var orders = _orderService.SearchOrders(userId: userId);

                byte[] bytes = null;
                using (var stream = new MemoryStream())
                {
                    _exportManager.ExportOrdersToXlsx(stream, orders);
                    bytes = stream.ToArray();
                }
                return File(bytes, "text/xls", "orders.xlsx");
            }
            catch (Exception exc)
            {
                return Content(exc.Message);
            }
        }

        public IActionResult ExportUserExcelAll(int userId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageAgents))
                return HttpUnauthorized();

            try
            {
                var invitees = _userService.GetInvitations(userId, 0, int.MaxValue);

                byte[] bytes = null;
                using (var stream = new MemoryStream())
                {
                    _exportManager.ExportUsersToXlsx(stream, invitees);
                    bytes = stream.ToArray();
                }
                return File(bytes, "text/xls", "users.xlsx");
            }
            catch (Exception exc)
            {
                return RedirectToAction("List");
            }
        }

        public IActionResult ExportBonusExcelAll(int userId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageAgents))
                return HttpUnauthorized();

            var agent = _userService.GetUserById(userId);
            if (agent == null)
                return NotFound();
            try
            {
                var agentBonusList = _agentService.GetList(agentId: userId, parentAgentId: userId);

                var invitees = _userService.GetInvitations(userId, 0, int.MaxValue);

                byte[] bytes = null;
                using (var stream = new MemoryStream())
                {
                    _exportManager.ExportAgentBonusToXlsx(stream, agentBonusList, agent);
                    bytes = stream.ToArray();
                }
                return File(bytes, "text/xls", string.Format("{0}-bonus.xlsx", agent.Id));
            }
            catch (Exception exc)
            {
                return RedirectToAction("List");
            }
        }

        #endregion

    }
}
